package com.ym.wcp.framework.mybatis;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.base.CaseFormat;
import com.ym.wcp.framework.utils.ClassUtil;
import org.springframework.util.StringUtils;

import javax.validation.constraints.NotNull;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.List;
import java.util.Objects;

/**
 * p配合 Wrapper 根据前端查询参数动态 拼装QueryWrapper
 */
public class QueryWrapperUtil {


    public static <T> void buildQueryWrapper(T t, QueryWrapper<?> queryWrapper) {
        List<Field> allFields = ClassUtil.getAllFields(t);
        for (Field field : allFields) {
            if (Modifier.isStatic(field.getModifiers())) {
                continue;
            }
            fieldToQueryWrapper(t, field, queryWrapper);
        }
    }

    public static <T> void buildQueryWrapperByDesc(T t, QueryWrapper<?> queryWrapper, String... column) {
        buildQueryWrapper(t, queryWrapper);
        queryWrapper.orderByDesc(column);
    }

    public static <T> void buildQueryWrapperByAsc(T t, QueryWrapper<?> queryWrapper, String... column) {
        buildQueryWrapper(t, queryWrapper);
        queryWrapper.orderByAsc(column);
    }

    @NotNull
    public static <T> void fieldToQueryWrapper(T t, Field field, QueryWrapper<?> queryWrapper) {
        try {
            field.setAccessible(true);
            Object fieldValue = field.get(t);
            String name = field.getName();
            Wrapper wrapper = field.getAnnotation(Wrapper.class);
            if (Objects.isNull(fieldValue)) {
                return;
            }
            if (Objects.nonNull(wrapper)) {
                WrapperKey keyword = wrapper.keyword();
                String wrapperField = StringUtils.isEmpty(wrapper.field()) ? CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, name) : wrapper.field();
                switch (keyword) {
                    case EQ:
                        queryWrapper.eq(wrapperField, fieldValue);
                        break;
                    case NE:
                        queryWrapper.ne(wrapperField, fieldValue);
                        break;
                    case LIKE:
                        queryWrapper.like(wrapperField, fieldValue);
                        break;
                    case LEFT_LIKE:
                        queryWrapper.likeLeft(wrapperField, fieldValue);
                        break;
                    case RIGHT_LIKE:
                        queryWrapper.likeRight(wrapperField, fieldValue);
                        break;
                    case NOT_LIKE:
                        queryWrapper.notLike(wrapperField, fieldValue);
                        break;
                    case GT:
                        queryWrapper.gt(wrapperField, fieldValue);
                        break;
                    case GE:
                        queryWrapper.ge(wrapperField, fieldValue);
                        break;
                    case LT:
                        queryWrapper.lt(wrapperField, fieldValue);
                        break;
                    case LE:
                        queryWrapper.le(wrapperField, fieldValue);
                        break;
                    case IN:
                        queryWrapper.in(wrapperField, fieldValue);
                        break;
                    case NOT_IN:
                        queryWrapper.notIn(wrapperField, fieldValue);
                        break;
                    case BETWEEN:
                        Between between = (Between) fieldValue;
                        queryWrapper.between(wrapperField, between.getBLeft(), between.getBRight());
                        break;
                    case ORDER_BY_DESC:
                        queryWrapper.orderByDesc(wrapperField);
                        break;
                    case ORDER_BY_ASC:
                        queryWrapper.orderByAsc(wrapperField);
                        break;
                }
            } else {
                String to = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, name);
                queryWrapper.eq(to, fieldValue);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
